package main.test.SparkAPI.Baics.scopes



//Public, the default access modifier
/**
 * Imagine you need to track the guests and costs of a party.
 * People registering for the event should be the only publicly accessible functionality.
 * The following snippet provides a possible implementation.
 */
class Party {
  var attendees = 0
  def register(guests:Int): Unit = {
    attendees += guests

    /**
     * Every time your code does not use an explicit access modifier, the
     * compiler applies the default access level, which is the public one. A
     * code element marked as public has no access restrictions:
     * anyone can see tis value and modify it. The public access level
     * doesn't have an explicit keyword;if you want to declare an element as public, you don't
     * provide any access modifier keyword.
     */
  }

  // Private
  /**
   * Let's look again at the snippet of code about registering attendees for an event
   * you implemented :
   * The variable attendees is publicly accessible: external users can
   * break your application by resetting its assignment
   * to any value of their choice. You can prevent this by marking the variable
   * attendees as private, making it no longer accessible outside the class party.
   */
  //private var attendees=0
}

/**
 * In scala, you use the private access modifier to prevent access to functions,
 * values, and classes that should not be used publicly; when a code element is private, you can
 * only access it from inside its class.
 *
 */


class Test {
  val configA = "I am public"
  private val configB = "I am private"
}
class MyPer {
  private val age = 18
}
class Myst extends MyPer


// Protected

/**
 * After tracking the number of attendees, suppose you need to estimate the cost
 * of an event.You don;t want this sensitive information to be public or have external
 * sources making changes to it. At the same time, you'd like to make this functionality reusable for any
 * event to ensure you can calculate costs consistently. In this case, you
 * can use the protected access modifier: a protected code element is
 * accessible only from its class and its subclass.Lets's see how
 * you could use the protected access modifier to control the
 * access to function computing the cost estimation of event.
 */
class Event {
  protected def estimateCosts(attendees: Int):Double =
    if (attendees < 10) 50.00 else attendees * 12.34
}

class Party02 extends Event {
  private var attendees = 0;
  var cost = estimateCosts(attendees)
  def register(gustets: Int) =
    attendees += gustets

  /**
   * The protected modifier allows code to be visible from the current class
   * and any code element that extends it,
   * such as a subclass or interface --- a topic that you'll discover in
   * lesson 12
    */

}

// Which access level to use?

/**
 * You have now learned several ways to change the visibility of your code.
 * When deciding which access level to use, the temptation of using the public default access level everywhere is quit
 * strong.But this not a good prac.Exposing your code as pubic
 * can be confusing for its users bec it makes its entry points challenging to identify.
 * By blocking access to portions of your program, you are preventing other
 * from overriding and improperly reusing them.Finally the more code you expose
 * to the public, the more complicated future changes will be: you
 * will not be able to control what parts of your system you can change without breaking external code
 * that depends on it. As a rule of thumb, pick the most restrictive access
 * modifier that satisfies your needs and avoid using the public access modifier unless strictly necessary.
 *
 */

object testScope {
  /**
   * Make your values, variables, functions, adn classes
   * accessible onley from their class
   * Limit your class accessiblity to a class and tis subclass
   * In lesson 9 ,you learned about packages.Protecting your code by limiting tis
   * accessibility is a good prac,esp when creating
   * external modules for third parties.
   * by doing so, you also reduce yor code;s public entry pints, making ti easier to use. THis approach also prevents external manipulations that
   * could expose sensitive data or introduce undisired behavior in your code
   * in this lesson, you'll learn about the Scala access modifiers, which are reserved keywords to
   * change your code elements' visibility. you
   * should use them to protect and hide information you should
   * not expose to the public.
   * You'll use access modifiers to implement auxiliary functions accessiblewithin their class in
   * the capstone.
   *
   */

  /**
   * Consider:
   * Suppose you are designing a program to manage bank accounts.
   * Your business requirements demand not to expose their balance unless
   * its owner requests it. How would you structure your code to enforce this
   * requirement?
   */

  def main(args: Array[String]): Unit = {
//    val test = new Test()
    val test = new Test
    println(test.configA)
    // TODO: error value configB in class Test cannot be accessed in main.test.SparkAPI.Baics.scopes.Test
    //    test.configB
    // test.configB

    val myst = new Myst


  }

}
